package org.smartboot.flow.core.manager;

import org.smartboot.flow.core.common.ComponentType;
import org.smartboot.flow.core.attribute.AttributeHolder;
import org.smartboot.flow.core.component.Component;
import org.smartboot.flow.core.util.AuxiliaryUtils;
import org.smartboot.flow.core.visitor.ComponentVisitor;
import org.smartboot.flow.core.visitor.ConditionVisitor;
import org.smartboot.flow.core.visitor.PipelineVisitor;

import java.util.List;
import java.util.Set;

/**
 * @author qinluo
 * @date 2022/11/19 12:27
 * @since 1.0.0
 */
public class RegisteredComponentVisitor extends ComponentVisitor {

    private final ComponentModel model;
    private final Set<Object> visited;

    public RegisteredComponentVisitor(ComponentModel comp, Set<Object> visited) {
        this.model = comp;
        this.visited = visited;
    }

    @Override
    public PipelineVisitor visitPipeline(String pipeline) {
        PipelineModel pipelineModel = new PipelineModel(pipeline, AuxiliaryUtils.contact(model.getIdentifier(), pipeline));
        this.model.pipeline = pipelineModel;
        return new RegisteredPipelineVisitor(pipelineModel, visited);
    }

    @Override
    public <T, S> void visitSource(Component<T, S> component) {
        this.model.setComponent(component);
    }

    @Override
    public ConditionVisitor visitCondition(String condition) {
        this.model.condition = (condition);
        return null;
    }

    @Override
    public ComponentVisitor visitComponent(ComponentType type, String name, String describe) {
        String identifier = AuxiliaryUtils.contact(model.getIdentifier(), AuxiliaryUtils.or(name, describe));
        String branch = null;
        if (this.model.type == ComponentType.CHOOSE) {
            identifier = AuxiliaryUtils.contact(model.getIdentifier(), "default");
            branch = "default";
        }

        ComponentModel comp = new ComponentModel(type, identifier);
        comp.setBranch(branch);
        this.model.addComponent(comp);
        return new RegisteredComponentVisitor(comp, visited);
    }

    @Override
    public void visitAttributes(List<AttributeHolder> attributes) {
        model.addAttributes(attributes);
    }

    @Override
    public ComponentVisitor visitBranch(Object branch, ComponentType type, String name, String describe) {
        ComponentModel model = new ComponentModel(type, AuxiliaryUtils.contact(this.model.getIdentifier(), "branch", String.valueOf(branch)));
        model.setBranch((String.valueOf(branch)));
        this.model.addComponent(model);
        return new RegisteredComponentVisitor(model, visited);
    }

    @Override
    public void visitExecutable(String executable) {
        this.model.executable = (executable);
    }
}
